/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	TaskScheduler.h
*
*	Description -	Tasking system that propagates tasks to worker threads.
*
*	Comments	-	Task scheduler creates n threads where n is the number of physical
*						CPU cores.
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	12/30/2011	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_TASK_SCHEDULER_H_
#define _PSX_TASK_SCHEDULER_H_

#include "PulseSTD.h"
#include "Singleton.h"
#include "Queue.h"
#include "SmartPointer.h"
#include "PriorityQueue.h"
#include "Array.h"
#include "Semaphore.h"
#include "Mutex.h"
#include "ThreadTask.h"
#include "ThreadWorker.h"

namespace Pulse
{
	#define PSX_MaxThreads 32

	class TaskScheduler : public Singleton<TaskScheduler>
	{
	public:

		virtual ~TaskScheduler( void );

		SIZE_T GetNumThreads( void ) { return m_numThreads; }

		BOOL IsShuttingDown( void ) { return m_bShuttingDown; }

		void WaitUntilWorkersReady( void );

		// Its not the task that the scheduler is really interested about.
		//	it gets the task status and waits until the task status is complete.
		void WorkUntilDone( ThreadTask *pTask );

		void AddTask( ThreadTask *pNewTask );

	private:

		// ThreadWorker functionality

		void SignalIdle( void );

		void WaitUntilResume( void );

		ThreadWorker * GetThreadWorker( INDEX_T index );

	private:

		// Engine functionality
		TaskScheduler( void );

		EErrorCode::Type Initialize( void );

		void Shutdown( void );

		void WakeWorkers( void );

	private:

		friend Singleton<TaskScheduler>;
		friend Engine;
		friend ThreadWorker;

		ThreadWorker	*m_pThreads[PSX_MaxThreads];
		SIZE_T			m_numThreads;
		INDEX_T			m_pushIndex;
		SemaphorePtr	m_pResumeSignal;
		AtomicInt		m_numIdleThreads;
		BOOL			m_bShuttingDown;

	};
}

#endif /* _PSX_TASK_SCHEDULER_H_ */